﻿using System;
using System.Collections.Generic;

namespace DataCoreTechnologies.SqlServer
{
   /// <summary>
   /// Contains information about a column that is tied to either a table or a view.
   /// </summary>
   public sealed class Column
   {
      #region Public
      //Properties
      /// <summary>
      /// A number that uniquely identifies this class instance.
      /// </summary>
      public Guid InstanceId { get; private set; }
      /// <summary>
      /// The table this column belongs to.
      /// </summary>
      public Table Table { get; internal set; }
      /// <summary>
      /// The view this column belongs to.
      /// </summary>
      public View View { get; internal set; }
      /// <summary>
      /// The title used to identify this column within the database.
      /// </summary>
      public string Name { get; internal set; }
      /// <summary>
      /// The data type this column is derives from.
      /// </summary>
      public SystemType SystemType { get; internal set; }
      /// <summary>
      /// When appropriate the user type this column derives from.
      /// </summary>
      public UserType UserType { get; internal set; }
      /// <summary>
      /// When appropriate the largest allowed size for this column.
      /// </summary>
      public int MaxLength { get; internal set; }
      /// <summary>
      /// The appropriate the level of precision for this column.
      /// </summary>
      public int Precision { get; internal set; }
      /// <summary>
      /// When appropriate the level of scale for this column.
      /// </summary>
      public int Scale { get; internal set; }
      /// <summary>
      /// The order this column appears in its table or view.
      /// </summary>
      public int Order { get; internal set; }
      /// <summary>
      /// When appropriate the collation used by this column.
      /// </summary>
      public string CollationName { get; internal set; }
      /// <summary>
      /// Indicator stating whether this column contains a computed value.
      /// </summary>
      public Boolean IsComputed { get; internal set; }
      /// <summary>
      /// Indicator stating whether this column is part of a primary key.
      /// </summary>
      public Boolean IsPrimaryKey { get; internal set; }
      /// <summary>
      /// Indicator stating whether this column allows null values.
      /// </summary>
      public Boolean IsNullable { get; internal set; }
      /// <summary>
      /// Indicator stating whether this column is part of a foreign key.
      /// </summary>
      public Boolean IsForeignKey { get; internal set; }
      /// <summary>
      /// A short description explaining the purpose of this column.
      /// </summary>
      public string Description { get; internal set; }
      /// <summary>
      /// Information about a default value assigned to this column.
      /// </summary>
      public DefaultValue DefaultValue { get; internal set; }
      /// <summary>
      /// Information about a check constraint being applied to this column.
      /// </summary>
      public CheckConstraint CheckConstraint { get; internal set; }
      /// <summary>
      /// Indicator stating whether this column is unique within its table or view.
      /// </summary>
      public Boolean IsUnique { 
         get {
             if (Table != null)
             {
                 foreach (Index index in Table.Indexes)
                 {
                     foreach (IndexColumn indexColumn in index.IndexColumns)
                     {
                         if (indexColumn.Column == this && index.IsUniqueConstraint == true)
                             return true;
                         else
                             return false;
                     }
                 }
             }
             else if (View != null)
             {
                 foreach (Index index in Table.Indexes)
                 {
                     foreach (IndexColumn indexColumn in index.IndexColumns)
                     {
                         if (indexColumn.Column == this && index.IsUniqueConstraint == true)
                             return true;
                         else
                             return false;
                     }
                 }
             }
             return false;
         } 
      }
      /// <summary>
      /// Collection of name / value pairs associated to this column.
      /// </summary>
      public IEnumerable<ExtendedProperty> ExtendedProperties
      {
         get
         {
             for (int index = 0; index < _extendedProperties.Count; index++)
             {
                 yield return _extendedProperties[index];
             }
         }
      }
      #endregion
      #region Internal
      //Constructors
      /// <summary>
      /// Creates an instance of a column.
      /// </summary>
      internal Column()
      {
         InstanceId = System.Guid.NewGuid();
      }
      //Properties
      /// <summary>
      /// A number used to identify this column within the database.
      /// </summary>
      internal int Id { get; set; }
      //Methods
      /// <summary>
      /// Associates a extended property to this column.
      /// </summary>
      /// <param name="extendedProperty">The extended property that is to be associated to this column.</param>
      internal void AddExtendedProperty(ExtendedProperty extendedProperty) { _extendedProperties.Add(extendedProperty); }
      #endregion
      #region Private
      //Properties
      private List<ExtendedProperty> _extendedProperties = new List<ExtendedProperty>();
      #endregion
   }
}
